package com.kingwang.study.spring.security.demo.security.handler;

import com.kingwang.study.spring.security.demo.security.token.session.TokenSessionManager;
import com.kingwang.study.spring.security.demo.util.HttpServletUtils;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 系统登出处理器
 */
@Component
public class SystemLogoutHandler implements LogoutHandler {
    private TokenSessionManager sessionManager;

    protected TokenSessionManager getSessionManager() {
        return this.sessionManager;
    }

    public SystemLogoutHandler(TokenSessionManager sessionManager) {
        this.sessionManager = sessionManager;
    }

    @SneakyThrows
    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        // 登出接口检查权限
        if (authentication == null) {
            HttpServletUtils.sendHttpStatusResponse(response, HttpStatus.FORBIDDEN);
            return;
        }

        // 清除FormsLogin的Session
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }

        // 清除Token
        final String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (StringUtils.isNotBlank(authorizationHeader)) {
            String[] tokenParts = authorizationHeader.split(" ");

            if (tokenParts.length == 2) {
                String tokenSessionId = this.sessionManager.generateSessionId(
                        tokenParts[0],
                        tokenParts[1]);

                getSessionManager().removeSession(tokenSessionId);
            } else {
                throw unsupportedOperationException("Token格式非法！");
            }
        }

        // 清除Spring Security Context
        SecurityContext context = SecurityContextHolder.getContext();
        context.setAuthentication(null);
        SecurityContextHolder.clearContext();

        HttpServletUtils.sendHttpStatusResponse(response, HttpStatus.OK);
    }

    private static UnsupportedOperationException unsupportedOperationException(String message) {
        return new UnsupportedOperationException(message);
    }
}
